
import re

# regexSimpleSelector = re.compile(r'([-\w]+|(#[-\w]+)|(\[[^\]]+\])|(:[-\w]+)|(\.[-\w]+))+(\s*>|\s*\+| |$)\s*')
# regexType = re.compile(r'^([-\w]*)')
# regexID = re.compile(r'#([-\w]+)|')
# regexAttributes = re.compile(r'\[[^\]]+\]')
# regexAttribute = re.compile(r'\[([-\w]+)(=|~=|\|=)?(["']?(.+?)["']?)?\]')
# regexPseudos = re.compile(r':[-\w]+')
# regexStyleNames = re.compile(r'\.[-\w]+')
# regexCombinator = re.compile(r'(>|\+| |)\s*$')
#   
# def cssToXpaths(css):
#   selectors = css.split(',')
#   xpaths = []
#   
#   for selector in selectors:
#     xpath = '//'
#     index = 0
#     
#     for match in regexSimpleSelector.finditer(selector):
#       ss = match.group(0)
#       xpath += regexType.search(ss).group(1) or "*"
#       id = regexID.search(ss).group(1)
#       xpath += id and '[@id="%s"]' % id or ''
#       combinator = regexCombinator.search(ss).group(1)
#       xpath += {'': '', ' ': '//', '>': '/', '+': '/following-sibling::*[0]'}[combinator]
#       
#       attributes = regexAttributes.findall(ss)
#       pseudos = regexPseudos.findall(ss)
#       styleNames = regexStyleNames.findall(ss)
#       
#       for styleName in styleNames:
#         attributes.append('[class~=%s]' % styleName[1:])
#       
#       for attribute in attributes:
#         match = regexAttribute.search(attribute)
#         name = '@' + match.group(1)
#         sign = match.group(2)
#         value = match.group(4)
#         if value:
#           value = '"%s"' % value
#         
#         if sign = '~=':
#           xpath += E[ contains(concat( " ", @foo, " " ), concat( " ", "warning", " " )) ]
#         else:
#           xpath += '[%s%s%s]'
#           
#           for each (att:String in attributes)
#           {
#             matches:Array = att.match(regexAttribute)
#             attribute:AttributeSelector = new AttributeSelector(normalizeAttribute(matches[1]))
#             if (matches[2])
#               attribute.matcher = matches[2]
#             
#             if (matches[4])
#               attribute.value = matches[4]
#             
#             simpleSelector.attributes.append(attribute)
#           }
#           
#           for each (pseudo:String in pseudos)
#           {
#             pseudo = pseudo.substr(1)
#             simpleSelector.pseudos.append(new PseudoSelector(pseudo))
#           }
#           selector.simpleSelectors.append(simpleSelector)
#         }
#       
#         selectors.append(selector)
#     xpaths.append(xpath)
#       
#   return xpaths
  

regElement = re.compile(r'^([#.]?)([a-z0-9\*_-]*)((\|)([a-z0-9\*_-]*))?', re.I)
regAttr1 = re.compile(r'^\[([^\]]*)\]', re.I)
regAttr2 = re.compile(r'^\[\s*([^~=\s]+)\s*(~?=)\s*"([^"]+)"\s*\]', re.I)
regPseudo = re.compile(r'^:([a-z_-])+', re.I)
regCombinator = re.compile(r'^(\s*[>+\s])?', re.I)
regComma = re.compile(r'^\s*,', re.I)


def cssToXpath(rule):

  index = 1
  parts = ["//", "*"]
  lastRule = null
  
  while len(rule) and rule != lastRule:
    lastRule = rule
    
    # Trim leading whitespace
    rule = rule.strip()
    if not len(rule):
      break
    
    # Match the element identifier
    m = regElement.search(rule)
    if m:
      if not m.group(1):
        if m.group(5):
          parts[index] = m.group(5)
        else:
          parts[index] = m.group(2)
      elif m.group(1) == '#':
        parts.append("[@id='%s']" % m.group(2))
      elif m.group(1) == '.':
        parts.append("[contains(@class, '%s')]" % m.group(2))
      
      rule = rule[len(m.group(0))]
    
    # Match attribute selectors
    m = regAttr2.search(rule)
    if m:
      if m.group(2) == "~=":
        parts.append("[contains(@%s, '%s')]" % (m.group(1), m.group(3)) )
      else:
        parts.append("[@%s='%s']" % (m.group(1), m.group(3)) )
      
      rule = rule[len(m.group(0))]
    
    else:
      
      m = regAttr1.search(rule)
      if m:
        parts.append("[@%]" % m.group(1))
        rule = rule[len(m.group(0))]
    
    # Skip over pseudo-classes and pseudo-elements, which are of no use to us
    m = regPseudo.search(rule)
    while m:
      rule = rule[len(m.group(0))]
      m = regPseudo.search(rule)
    
    # Match combinators
    m = regCombinator.search(rule)
    if m and len(m.group[0]):
      if m.gropu(0).find(">") != -1:
        parts.append("/")
      elif m.group(0).find("+") != -1:
        parts.append("/following-sibling::")
      else:
        parts.append("//")

      index = len(parts)
      parts.append("*")
      rule = rule[len(m.group(0))]
    
    m = regComma.search(rule)
    if m:
      parts += [" | ", "//", "*"]
      index = len(parts)-1
      rule = rule[len(m.group(0))]
      
  
  xpath = ''.join(parts)
  return xpath
